package com.pai4j.pgc.controller;

import com.pai4j.common.bean.PAIPageResponseBeanUtil;
import com.pai4j.common.bean.PAIResponseBean;
import com.pai4j.common.bean.PAIResponseBeanUtil;
import com.pai4j.domain.vo.request.subjectaccount.SaveArticleRequestVO;
import com.pai4j.domain.vo.response.subjectaccount.ArticleBaseResponseVO;
import com.pai4j.domain.vo.response.subjectaccount.UserArticleStatisticsVO;
import com.pai4j.log.annotation.OperationLog;
import com.pai4j.pgc.service.ArticleStatisticsService;
import com.pai4j.pgc.service.SubjectArticleService;
import com.pai4j.remote.pgc.SubjectArticleClient;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.Map;

@RestController
public class SubjectArticleController implements SubjectArticleClient {

    @Resource
    private SubjectArticleService subjectArticleService;

    @Resource
    private ArticleStatisticsService articleStatisticsService;
    
    
    /**
     * 提交文章接口
     * 该方法接收一个保存文章的请求对象，调用文章服务的提交方法处理文章提交逻辑
     * 主要用于文章创作时的提交操作
     *
     * @param saveArticleRequest 文章保存请求对象，包含文章的必要信息
     * @return 返回一个包含文章ID的API响应对象，表示提交结果
     */
    @Override
    @OperationLog(
        module = "文章管理",
        operation = "提交文章",
        description = "用户提交新文章",
        recordParams = true
    )
    public PAIResponseBean<Long> submit(@RequestBody SaveArticleRequestVO saveArticleRequest) {
    
            return PAIResponseBeanUtil.success(subjectArticleService.submit(saveArticleRequest));
        }
    
    /**
     * 编辑文章接口（统一接口，支持草稿和已发布文章的编辑）
     * 该方法可以编辑任何状态的文章，包括草稿、待推送和已发布的文章
     * 编辑时保持原状态不变，只更新文章内容和信息
     *
     * @param saveArticleRequest 文章保存请求对象（必须包含articleId）
     * @return 返回一个包含文章ID的API响应对象，表示编辑结果
     */
    @Override
    @OperationLog(
        module = "文章管理",
        operation = "编辑文章",
        description = "用户编辑文章",
        recordParams = true
    )
    public PAIResponseBean<Long> editArticle(@RequestBody SaveArticleRequestVO saveArticleRequest) {
        return PAIResponseBeanUtil.success(subjectArticleService.editArticle(saveArticleRequest));
    }
    
    
    /**
     * 保存草稿文章接口
     * 该方法接收一个保存文章的请求对象，调用文章服务的草稿保存方法处理文章草稿保存逻辑
     * 主要用于文章创作时的草稿保存操作
     *
     * @param saveArticleRequest 文章保存请求对象，包含文章的必要信息
     * @return 返回一个包含文章ID的API响应对象，表示保存结果
     */
    @Override
    @OperationLog(
            module = "文章管理",
            operation = "保存草稿",
            description = "用户保存文章草稿",
            recordParams = true
    )
    public PAIResponseBean<Long> saveDraft(@RequestBody SaveArticleRequestVO saveArticleRequest) {
        return PAIResponseBeanUtil.success(subjectArticleService.saveDraft(saveArticleRequest));
    }
    
    /**
     * 文章详情接口
     * 根据文章ID和是否需要内容的标志，从缓存中获取文章详情
     * 主要用于查看文章详细信息，可根据需求选择是否加载文章内容
     *
     * @param id 文章ID，用于标识特定的文章
     * @param isNeedContent 标志是否需要文章内容，true表示需要，false表示不需要
     * @return 返回一个包含文章基本信息响应对象的API响应，表示查询结果
     */
    @Override
    public PAIResponseBean<ArticleBaseResponseVO> detail(Long id, Boolean isNeedContent) {
    
            ArticleBaseResponseVO articleVo =
                    subjectArticleService.getArticleDetailFromCache(id, ObjectUtils.equals(isNeedContent, true));
            return PAIResponseBeanUtil.success(articleVo);
        }
    
    /**
     * 文章分页查询接口: 只查询当前登录用户已发布的文章
     * 根据页码和每页大小，获取文章列表的分页信息
     * 主要用于浏览多篇文章时的分页查询，以便用户可以按页查看文章
     *
     * @param pageNo 页码，表示请求的页数
     * @param pageSize 每页大小，表示每页包含的文章数量
     * @return 返回一个包含文章列表分页响应对象的API响应，表示查询结果
     */
    @Override
    public PAIResponseBean<PAIPageResponseBeanUtil<ArticleBaseResponseVO>> pageAuthorAndStatusAndPublish(Integer pageNo, Integer pageSize, String author) {
    
            return PAIResponseBeanUtil.success(subjectArticleService.pageAuthorAndStatusAndPublish(pageNo, pageSize, author));
        }
    
    /**
     * 文章分页查询接口: 只查询当前登录用户草稿的文章
     * 根据页码和每页大小，获取文章列表的分页信息
     * 主要用于浏览多篇文章时的分页查询，以便用户可以按页查看文章
     *
     * @param pageNo 页码，表示请求的页数
     * @param pageSize 每页大小，表示每页包含的文章数量
     * @return 返回一个包含文章列表分页响应对象的API响应，表示查询结果
     */
    @Override
    public PAIResponseBean<PAIPageResponseBeanUtil<ArticleBaseResponseVO>> pageAuthorAndStatusAndDraft(Integer pageNo, Integer pageSize, String author) {
        
        return PAIResponseBeanUtil.success(subjectArticleService.pageAuthorAndStatusAndDraft(pageNo, pageSize, author));
    }
    
    
    
    @Override
    public PAIResponseBean<PAIPageResponseBeanUtil<ArticleBaseResponseVO>> pageStatus(Integer pageNo, Integer pageSize) {
        return PAIResponseBeanUtil.success(subjectArticleService.pageStatus(pageNo, pageSize));
    }
    
    
    /**
     * 文章分页查询接口
     * 根据页码和每页大小和作者，获取文章列表的分页信息
     * 主要用于浏览多篇文章时的分页查询，以便用户可以按页查看文章
     *
     * @param pageNo 页码，表示请求的页数
     * @param pageSize 每页大小，表示每页包含的文章数量
     * @return 返回一个包含文章列表分页响应对象的API响应，表示查询结果
     */
    @Override
    public PAIResponseBean<PAIPageResponseBeanUtil<ArticleBaseResponseVO>> page(Integer pageNo, Integer pageSize) {
        
        return PAIResponseBeanUtil.success(subjectArticleService.page(pageNo, pageSize));
    }
    
    
    /**
     * 批量获取文章详情接口
     * 根据文章ID列表，批量从缓存中获取文章详情
     * 主要用于需要同时查看多篇文章详细信息的场景，提高查询效率
     *
     * @param articleIds 文章ID列表，用于标识需要获取详情的多篇文章
     * @return 返回一个包含多篇文章基本信息响应对象的API响应，表示查询结果
     */
    @Override
    public PAIResponseBean<Map<Long, ArticleBaseResponseVO>> batchGet(@RequestBody List<Long> articleIds) {
    
            return PAIResponseBeanUtil.success(subjectArticleService.batchGetArticleDetailFromCache(articleIds));
        }
        
        /**
         * 根据文章id生成文章海报
         *
         * @author: CYM-pai
         * @date: 2025/04/30 19:52
         **/
        
    @Override
    public PAIResponseBean<String> getPoster(Long articleId){
        //1、根据id 获取文章信息
        ArticleBaseResponseVO articleBaseResponseVO = this.detail(articleId, true).getData();
        //2、调用service生成海报
        return PAIResponseBeanUtil.success(subjectArticleService.getPoster(articleBaseResponseVO));
        }
    
   
    
    /**
     *  获取专题文章分页查询接口
     *
     * @author: CYM-pai
     * @date: 2025/07/08 10:40
     **/
    @Override
    public PAIResponseBean<PAIPageResponseBeanUtil<List<ArticleBaseResponseVO>>> pageSubjectArticleList(Integer pageNo, Integer pageSize, Long subjectAccount) {
        return PAIResponseBeanUtil.success(subjectArticleService.getSubjectArticleList(pageNo, pageSize, subjectAccount));
    }
    
    
    
    /**
     *  获取专题已推送文章分页查询接口
     *
     * @author: CYM-pai
     * @date: 2025/07/12 22:40
     **/
    @Override
    public PAIResponseBean<PAIPageResponseBeanUtil<List<ArticleBaseResponseVO>>> pageSubjectArticleListByStatus(Integer pageNo, Integer pageSize, Long subjectAccount) {
        return PAIResponseBeanUtil.success(subjectArticleService.pageSubjectArticleListByStatus(pageNo, pageSize, subjectAccount));
    }
    
    
    
    /**
     * 分页查询指定作者的草稿文章接口
     * 根据页码、每页大小和作者，获取草稿文章列表的分页信息
     * 主要用于作者查看自己的草稿文章
     *
     * @param pageNo 页码，表示请求的页数
     * @param pageSize 每页大小，表示每页包含的文章数量
     * @param author 作者，表示要查询的作者
     * @return 返回一个包含草稿文章列表分页响应对象的API响应，表示查询结果
     */
    @Override
    public PAIResponseBean<PAIPageResponseBeanUtil<ArticleBaseResponseVO>> pageDraftsByAuthor(Integer pageNo, Integer pageSize, String author) {
        return PAIResponseBeanUtil.success(subjectArticleService.pageDraftsByAuthor(pageNo, pageSize, author));
    }
    
    /**
     * 分页查询指定专题的草稿文章接口
     * 根据页码、每页大小和专题账户，获取草稿文章列表的分页信息
     * 主要用于专题管理者查看专题下的草稿文章
     *
     * @param pageNo 页码，表示请求的页数
     * @param pageSize 每页大小，表示每页包含的文章数量
     * @param subjectAccount 专题账户，表示要查询的专题
     * @return 返回一个包含草稿文章列表分页响应对象的API响应，表示查询结果
     */
    @Override
    public PAIResponseBean<PAIPageResponseBeanUtil<ArticleBaseResponseVO>> pageDraftsBySubject(Integer pageNo, Integer pageSize, String subjectAccount) {
        return PAIResponseBeanUtil.success(subjectArticleService.pageDraftsBySubject(pageNo, pageSize, subjectAccount));
    }
    
    /**
     * 将草稿文章发布为待推送状态接口
     * 该方法将草稿状态的文章转换为待推送状态，并加入推送队列
     * 主要用于草稿文章的发布操作
     *
     * @param articleId 文章ID，用于标识特定的文章
     * @param author 作者，用于权限验证
     * @param planPushTime 计划推送时间，可选参数
     * @return 返回一个包含文章ID的API响应对象，表示发布结果
     */
    @Override
    @OperationLog(
        module = "文章管理",
        operation = "发布草稿",
        description = "用户发布草稿文章",
        recordParams = true
    )
    public PAIResponseBean<Long> publishDraft(Long articleId, String author, Long planPushTime) {
        return PAIResponseBeanUtil.success(subjectArticleService.publishDraft(articleId, author, planPushTime));
    }
    
    /**
     * 统计指定作者的草稿数量接口
     * 根据作者统计其草稿文章的数量
     * 主要用于作者了解自己的草稿文章数量
     *
     * @param author 作者，表示要统计的作者
     * @return 返回一个包含草稿数量的API响应对象
     */
    @Override
    public PAIResponseBean<Long> countDraftsByAuthor(String author) {
        return PAIResponseBeanUtil.success(subjectArticleService.countDraftsByAuthor(author));
    }
    
    /**
     * 统计指定专题的草稿数量接口
     * 根据专题账户统计其草稿文章的数量
     * 主要用于专题管理者了解专题下的草稿文章数量
     *
     * @param subjectAccount 专题账户，表示要统计的专题
     * @return 返回一个包含草稿数量的API响应对象
     */
    @Override
    public PAIResponseBean<Long> countDraftsBySubject(String subjectAccount) {
        return PAIResponseBeanUtil.success(subjectArticleService.countDraftsBySubject(subjectAccount));
    }

    /**
     * 获取用户文章统计信息接口
     * 统计指定作者的已发布文章数、草稿数、文章总浏览数等信息
     * 该接口使用Redis缓存以提高查询性能，缓存时间为1小时
     *
     * @param author 作者ID，表示要查询统计信息的用户
     * @return 返回一个包含用户文章统计信息的API响应对象
     */
    @Override
    public PAIResponseBean<UserArticleStatisticsVO> getUserArticleStatistics(String author) {
        return PAIResponseBeanUtil.success(articleStatisticsService.getUserArticleStatistics(author));
    }

    /**
     * 分页查询指定作者的文章（支持状态过滤）
     * 可以通过status参数过滤不同状态的文章（草稿、待推送、已推送）
     *
     * @param pageNo 页码
     * @param pageSize 每页大小
     * @param author 作者
     * @param status 文章状态（可选，null表示查询所有状态）
     * @return 文章分页列表
     */
    @Override
    public PAIResponseBean<PAIPageResponseBeanUtil<ArticleBaseResponseVO>> pageAuthorWithStatus(
            Integer pageNo, Integer pageSize, String author, Integer status) {
        return PAIResponseBeanUtil.success(subjectArticleService.pageAuthor(pageNo, pageSize, author, status));
    }

    /**
     * 分页查询指定专题的文章（支持状态过滤）
     * 可以通过status参数过滤不同状态的文章（草稿、待推送、已推送）
     *
     * @param pageNo 页码
     * @param pageSize 每页大小
     * @param subjectAccount 专题账户
     * @param status 文章状态（可选，null表示查询所有状态）
     * @return 文章分页列表
     */
    @Override
    public PAIResponseBean<PAIPageResponseBeanUtil<ArticleBaseResponseVO>> pageSubjectWithStatus(
            Integer pageNo, Integer pageSize, String subjectAccount, Integer status) {
        return PAIResponseBeanUtil.success(subjectArticleService.pageBySubject(pageNo, pageSize, subjectAccount, status));
    }

    /**
     * 获取文章详情（带权限控制）
     * 草稿状态的文章只允许作者本人查看
     *
     * @param articleId 文章ID
     * @param isNeedContent 是否需要内容
     * @param currentUserId 当前用户ID（用于权限验证）
     * @return 文章详情
     */
    @Override
    public PAIResponseBean<ArticleBaseResponseVO> detailWithPermission(
            Long articleId, Boolean isNeedContent, String currentUserId) {
        ArticleBaseResponseVO article = subjectArticleService.getArticleDetailWithPermission(
                articleId, ObjectUtils.equals(isNeedContent, true), currentUserId);
        return PAIResponseBeanUtil.success(article);
    }

    /**
     * 删除文章接口（逻辑删除）
     * 删除指定文章，只有作者本人有权限删除
     * 采用逻辑删除，文章数据会保留在数据库中，便于数据分析和可能的恢复
     * 删除后会同时清除Redis缓存
     *
     * @param articleId 文章ID
     * @param author 作者（用于权限验证）
     * @return 是否删除成功
     */
    @Override
    @OperationLog(
        module = "文章管理",
        operation = "删除文章",
        description = "用户逻辑删除文章",
        recordParams = true
    )
    public PAIResponseBean<Boolean> deleteArticle(Long articleId, String author) {
        return PAIResponseBeanUtil.success(subjectArticleService.deleteArticle(articleId, author));
    }

    /**
     * 恢复已删除的文章接口
     * 将逻辑删除的文章恢复为正常状态
     * 只有作者本人有权限恢复
     * 恢复后会重新加入缓存
     *
     * @param articleId 文章ID
     * @param author 作者（用于权限验证）
     * @return 是否恢复成功
     */
    @Override
    @OperationLog(
        module = "文章管理",
        operation = "恢复文章",
        description = "用户恢复已删除的文章",
        recordParams = true
    )
    public PAIResponseBean<Boolean> restoreArticle(Long articleId, String author) {
        return PAIResponseBeanUtil.success(subjectArticleService.restoreArticle(articleId, author));
    }

    /**
     * 分页查询指定作者已删除的文章接口（回收站）
     * 查询用户已删除的文章列表，用于回收站功能
     * 只有作者本人可以查看自己删除的文章
     *
     * @param pageNo 页码
     * @param pageSize 每页大小
     * @param author 作者
     * @return 已删除文章分页列表
     */
    @Override
    public PAIResponseBean<PAIPageResponseBeanUtil<ArticleBaseResponseVO>> pageDeletedByAuthor(
            Integer pageNo, Integer pageSize, String author) {
        return PAIResponseBeanUtil.success(subjectArticleService.pageDeletedByAuthor(pageNo, pageSize, author));
    }

    /**
     * 更新文章状态接口
     * 用于草稿转发布、发布转草稿等状态变更
     * 只有作者本人有权限更新状态
     *
     * @param articleId 文章ID
     * @param author 作者（用于权限验证）
     * @param newStatus 新状态
     * @return 是否更新成功
     */
    @Override
    @OperationLog(
        module = "文章管理",
        operation = "更新文章状态",
        description = "用户更新文章状态",
        recordParams = true
    )
    public PAIResponseBean<Boolean> updateArticleStatus(Long articleId, String author, Integer newStatus) {
        return PAIResponseBeanUtil.success(subjectArticleService.updateArticleStatus(articleId, author, newStatus));
    }
    
    
    
    /**
     * 文章pdf导出接口
     * TODO: 2025/04/30 20:02
     * @author: CYM-pai
     * @date: 2025/04/30 20:02
     **/
    
    @Override
    public PAIResponseBean<String> exportPdf(Long articleId){
        //1、根据id 获取文章信息
        ArticleBaseResponseVO articleBaseResponseVO = this.detail(articleId, true).getData();
        //2、调用service生成pdf
        return PAIResponseBeanUtil.success(SubjectArticleService.getPDF(articleBaseResponseVO));
    }
    /**
     * 文章word导出接口
     * TODO: 2025/04/30 20:05
     * @author: CYM-pai
     * @date: 2025/04/30 20:05
     **/
    @Override
    public PAIResponseBean<String> exportWord(Long articleId){
        //1、根据id 获取文章信息
        ArticleBaseResponseVO articleBaseResponseVO = this.detail(articleId, true).getData();
        //2、调用service生成word文档
        return PAIResponseBeanUtil.success(SubjectArticleService.getWORD(articleBaseResponseVO));
    }
    
    /**
     * 批量逻辑删除文章接口
     * 根据文章ID列表批量删除文章，所有文章必须属于同一作者
     * 采用逻辑删除，文章数据会保留在数据库中
     * 删除后会同时清除Redis缓存
     *
     * @param articleIds 文章ID列表
     * @param author 作者（用于权限验证）
     * @return 成功删除的文章数量
     */
    @Override
    @OperationLog(
        module = "文章管理",
        operation = "批量删除文章",
        description = "用户批量逻辑删除文章",
        recordParams = true
    )
    public PAIResponseBean<Integer> batchDeleteArticles(List<Long> articleIds, String author) {
        return PAIResponseBeanUtil.success(subjectArticleService.batchDeleteArticles(articleIds, author));
    }
    
    /**
     * 批量恢复已删除的文章接口
     * 根据文章ID列表批量恢复文章，所有文章必须属于同一作者
     * 恢复后会重新加入缓存
     *
     * @param articleIds 文章ID列表
     * @param author 作者（用于权限验证）
     * @return 成功恢复的文章数量
     */
    @Override
    @OperationLog(
        module = "文章管理",
        operation = "批量恢复文章",
        description = "用户批量恢复已删除的文章",
        recordParams = true
    )
    public PAIResponseBean<Integer> batchRestoreArticles(List<Long> articleIds, String author) {
        return PAIResponseBeanUtil.success(subjectArticleService.batchRestoreArticles(articleIds, author));
    }
    
    /**
     * 统计某专题下已发布文章的数量接口
     * 统计指定专题的已发布文章数量（状态为已推送，过滤已删除）
     *
     * @param subjectAccount 专题账户
     * @return 已发布文章数量
     */
    @Override
    public PAIResponseBean<Long> countPublishedArticlesBySubject(String subjectAccount) {
        return PAIResponseBeanUtil.success(subjectArticleService.countPublishedArticlesBySubject(subjectAccount));
    }
    
    /**
     * 统计某专题下文章的总数量接口（不过滤状态）
     * 统计指定专题的所有未删除文章数量，不区分状态
     *
     * @param subjectAccount 专题账户
     * @return 文章总数量
     */
    @Override
    public PAIResponseBean<Long> countTotalArticlesBySubject(String subjectAccount) {
        return PAIResponseBeanUtil.success(subjectArticleService.countTotalArticlesBySubject(subjectAccount));
    }
    
    /**
     * 物理删除文章接口（管理员专用）
     * 直接从数据库中删除文章记录，无法恢复
     * 该操作需要管理员权限，请谨慎使用
     *
     * @param articleId 文章ID
     * @param adminUser 管理员用户（用于审计记录）
     * @return 是否删除成功
     */
    @Override
    @OperationLog(
        module = "文章管理",
        operation = "物理删除文章（管理员）",
        description = "管理员物理删除文章（危险操作）",
        recordParams = true
    )
    public PAIResponseBean<Boolean> physicalDeleteArticle(Long articleId, String adminUser) {
        return PAIResponseBeanUtil.success(subjectArticleService.physicalDeleteArticle(articleId, adminUser));
    }
    
    /**
     * 批量物理删除文章接口（管理员专用）
     * 直接从数据库中删除文章记录，无法恢复
     * 该操作需要管理员权限，请谨慎使用
     *
     * @param articleIds 文章ID列表
     * @param adminUser 管理员用户（用于审计记录）
     * @return 成功删除的文章数量
     */
    @Override
    @OperationLog(
        module = "文章管理",
        operation = "批量物理删除文章（管理员）",
        description = "管理员批量物理删除文章（危险操作）",
        recordParams = true
    )
    public PAIResponseBean<Integer> batchPhysicalDeleteArticles(List<Long> articleIds, String adminUser) {
        return PAIResponseBeanUtil.success(subjectArticleService.batchPhysicalDeleteArticles(articleIds, adminUser));
    }
    
}
